#-*-coding: utf-8-*-

import initenv

# Version: 0.1
# Author: Don Li <iedon@126.com>
# License: Copyright(c) 2017 Don.Li
# Summary:

import sys
import asyncio

from aiohttp.web   import Application, run_app
from aiohttp.log   import web_logger
from config_parser import config
from const         import TEMPLATE_PATH, STATIC_PATH
from log           import log, logger

import jinja2
import aiohttp_jinja2

def init_routers(app):
    from route import ROUTERs

    for method, uri_pattern, handler in ROUTERs:
        app.router.add_route(method, uri_pattern, handler)
    app.router.add_static('/static', STATIC_PATH)

async def init(loop):
    from services.dispatcher import dispatcher

    _host, _port = config.get('SPIKER', 'port').split(':')
    app = Application(loop=loop, logger=log)

    aiohttp_jinja2.setup(app,
            loader = jinja2.FileSystemLoader(TEMPLATE_PATH))

    init_routers(app)

    log.info("Initialized, listening at {0}:{1}...".format(_host, _port))
    app.on_shutdown.append(dispatcher.stop)

    logger.add_handler(web_logger, config.get_value('LOG_LEVEL'))

    handler = app.make_handler(access_log=web_logger)
    srv = await loop.create_server(handler, _host, int(_port))

    return app, srv, handler

_stopped = False
def stop(loop, app, srv, handler):
    global _stopped

    log.debug("Server stopping: <{0}>...".format(_stopped))

    if _stopped: return
    _stopped = True

    srv.close()
    #loop.run_until_complete(srv.wait_closed())
    loop.run_until_complete(app.shutdown())
    loop.run_until_complete(handler.shutdown(60.0))
    loop.run_until_complete(app.cleanup())

    loop.close()

def main():
    log.initialize('SPIKER', config.get_value('LOG_LEVEL'))

    log.debug("Logger initialized. begin start server...")
    loop = asyncio.get_event_loop()

    app, srv, handler = loop.run_until_complete(init(loop))
    loop.add_signal_handler(30, stop, loop, app, srv, handler)

    try:
        log.debug("Server is running...")
        loop.run_forever()
    except KeyboardInterrupt:
        pass
    finally:
        stop(loop, app, srv, handler)

    log.info("Server is stopped...")

if __name__ == '__main__': main()
